﻿using System.Collections;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Gavel.Common.Component.Extension;
using Gavel.Common.Component.Model;

namespace Gavel.Common.Component.Controls;

/// <summary>
/// 表格
/// </summary>
public class Table : Control
{
    /// <summary>
    /// 静态构造绑定样式
    /// </summary>
    static Table() => DefaultStyleKeyProperty.OverrideDefaultStyle<Table>();

    /// <summary>
    /// 项目来源
    /// </summary>
    public static readonly DependencyProperty ItemsSourceProperty = nameof(ItemsSourceProperty).Register<Table, IEnumerable>();

    /// <summary>
    /// 项目来源
    /// </summary>
    public IEnumerable ItemsSource
    {
        get => (IEnumerable)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    /// <summary>
    /// 表格列
    /// </summary>
    public static readonly DependencyProperty ColumnsProperty = nameof(ColumnsProperty).Register<Table, ObservableCollection<TableColumn>>
    (
        new PropertyMetadata(new ObservableCollection<TableColumn>())
    );

    /// <summary>
    /// 表格列
    /// </summary>
    public ObservableCollection<TableColumn> Columns
    {
        get => (ObservableCollection<TableColumn>)GetValue(ColumnsProperty);
        set => SetValue(ColumnsProperty, value);
    }

    /// <summary>
    /// 无数据提示
    /// </summary>
    public static readonly DependencyProperty NoDataContentProperty = nameof(NoDataContentProperty).Register<Table, object>(new PropertyMetadata("暂无数据"));

    /// <summary>
    /// 无数据提示
    /// </summary>
    public object NoDataContent
    {
        get => GetValue(NoDataContentProperty);
        set => SetValue(NoDataContentProperty, value);
    }

    /// <summary>
    /// 头部栅格
    /// </summary>
    private Grid? _headerGrid;

    /// <summary>
    /// 行控件
    /// </summary>
    private ItemsControl? _itemsControl;

    /// <summary>
    /// 默认构造绑定事件
    /// </summary>
    public Table()
    {
        Columns.CollectionChanged += (_, _) => UpdateColumns();
    }

    /// <summary>
    /// 模板应用时调用
    /// </summary>
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _headerGrid = GetTemplateChild("HeaderGrid") as Grid;
        _itemsControl = GetTemplateChild("PART_ItemsControl") as ItemsControl;
        UpdateColumns();
    }

    /// <summary>
    /// 更新表格列
    /// </summary>
    private void UpdateColumns()
    {
        if (_headerGrid == null || _itemsControl == null)
        {
            return;
        }

        _headerGrid.ColumnDefinitions.Clear();
        _headerGrid.Children.Clear();
        for (int index = 0; index < Columns.Count; index++)
        {
            TableColumn column = Columns[index];
            ColumnDefinition headerCol = new ColumnDefinition
            {
                Width = column.Width,
                MinWidth = column.MinWidth
            };

            _headerGrid.ColumnDefinitions.Add(headerCol);
            TextBlock headerContent = new TextBlock { Text = column.Header };
            headerContent.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
            headerContent.SetValue(FontWeightProperty, FontWeights.Bold);
            headerContent.SetValue(FontSizeProperty, FontSize);
            headerContent.SetValue(MarginProperty, new Thickness(index == 0 ? 0 : 2, 0, index == Columns.Count - 1 ? 0 : 2, 0));
            Grid.SetColumn(headerContent, index);
            _headerGrid.Children.Add(headerContent);
        }

        _itemsControl.ItemTemplate = CreateDataTemplate();
    }

    /// <summary>
    /// 创建行单元格数据模板
    /// </summary>
    /// <returns>行单元格数据模板</returns>
    private DataTemplate CreateDataTemplate()
    {
        DataTemplate dataTemplate = new DataTemplate();
        FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid));
        for (int index = 0; index < Columns.Count; index++)
        {
            TableColumn column = Columns[index];
            FrameworkElementFactory colDef = new FrameworkElementFactory(typeof(ColumnDefinition));
            colDef.SetValue(ColumnDefinition.WidthProperty, column.Width);
            colDef.SetValue(ColumnDefinition.MinWidthProperty, column.MinWidth);
            // 相同共享组
            gridFactory.AppendChild(colDef);
            FrameworkElementFactory contentFactory = new FrameworkElementFactory(typeof(ContentPresenter));
            contentFactory.SetValue(Grid.ColumnProperty, index);
            contentFactory.SetValue(MarginProperty, new Thickness(index == 0 ? 0 : 2, 0, index == Columns.Count - 1 ? 0 : 2, 0));
            contentFactory.SetBinding
            (
                ContentPresenter.ContentTemplateProperty,
                new Binding($"Columns[{index}].CellTemplate")
                {
                    RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Table), 1)
                }
            );
            contentFactory.SetBinding(ContentPresenter.ContentProperty, new Binding());
            gridFactory.AppendChild(contentFactory);
        }

        dataTemplate.VisualTree = gridFactory;
        return dataTemplate;
    }
}